﻿<link rel="stylesheet" type="text/css" href="libs/codemirror/lib/codemirror.css" />
<script type="text/javascript" src="libs/jquery/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="libs/chroma.min.js"></script>
<script type="text/javascript" src="libs/codemirror/lib/codemirror.js"></script>
<script type="text/javascript" src="libs/codemirror/mode/javascript/javascript.js"></script>

<script type="text/javascript">
    (function ($) {
        $('code.lang-js').each(function () {
            var code = this;

            var cm = CodeMirror(
                function (elt) {
                    code.parentNode.replaceChild(elt, code);
                },
                {
                    value: code.innerHTML.trim(),
                    indentUnit: 4,
                    mode: 'javascript'
                }
            );

            cm.on('update', function (_cm, change) {
                showColors(_cm);
            });

            var resDisplay = $('<div class="result-display" />').appendTo(
                cm.display.wrapper.parentNode
            );

            showColors(cm);

            function showColors(cm) {
                $('.cm-string', cm.display.wrapper).each(styleSpan);
                $('.cm-number', cm.display.wrapper).each(enableSlider);

                // evaluate script
                var src = cm.getDoc().getValue();
                //resDisplay.html('');
                try {
                    var s = src.split(';').map(eval);
                    resDisplay.html(
                        '<ol><li>' +
                            s
                                .map(resRec)
                                .filter(function (d) {
                                    return d !== undefined;
                                })
                                .join('</li><li>') +
                            '</li></ol>'
                    );

                    $('.cm-string', resDisplay).each(styleSpan);
                } catch (e) {
                    // console.warn(e);
                }

                function resRec(d) {
                    if ($.isArray(d)) {
                        return '[' + d.map(d.length > 2 ? resShort : resLong).join(',') + ']';
                    }
                    return resLong(d);

                    function resLong(d) {
                        if (typeof d == 'boolean') {
                            return '<span class="cm-number">' + (d ? 'true' : 'false') + '</span>';
                        } else if (typeof d == 'string') {
                            // string color, e.g. hex value
                            return '<span class="cm-string">"' + d + '"</span>';
                        } else if (typeof d == 'object' && d._rgb) {
                            // chroma.js object
                            return (
                                '<span class="cm-string cm-color" data-color="' +
                                d.css() +
                                '">' +
                                d.hex() +
                                '</span>'
                            );
                        } else if ($.isNumeric(d)) {
                            return '<span class="cm-number">' + round(d, 3) + '</span>';
                        } else if ($.isFunction(d)) {
                            var s = '';
                            var dom = d.domain ? d.domain() : [0, 1],
                                dmin = Math.min(dom[0], dom[dom.length - 1]),
                                dmax = Math.max(dom[dom.length - 1], dom[0]);
                            for (var i = 0; i <= 100; i++) {
                                s +=
                                    '<span class="grad-step" style="background-color:' +
                                    d(dmin + (i / 100) * (dmax - dmin)) +
                                    '"></span>';
                            }
                            s += '<span class="domain-min">' + dmin + '</span>';
                            s += '<span class="domain-med">' + (dmin + dmax) * 0.5 + '</span>';
                            s += '<span class="domain-max">' + dmax + '</span>';
                            return '<div class="gradient">' + s + '</div>';
                        }
                    }

                    function resShort(d) {
                        if (typeof d == 'string') {
                            // string color, e.g. hex value
                            return (
                                '<span class="cm-string cm-color cm-small" data-color="' +
                                d +
                                '"><span class="cm-hidden-text">\'' +
                                chroma(d).hex() +
                                "'</span></span>"
                            );
                        } else if (typeof d == 'object' && d._rgb) {
                            // chroma.js object
                            return (
                                '<span class="cm-string cm-color cm-small" data-color="' +
                                d.css() +
                                '"><span class="cm-hidden-text">\'' +
                                d.hex() +
                                "'</span></span>"
                            );
                        } else if ($.isNumeric(d)) {
                            return '<span class="cm-number">' + round(d, 2) + '</span>';
                        } else if (isNaN(d)) {
                            return '<span class="cm-number cm-nan">NaN</span>';
                        }
                    }

                    function round(d, p) {
                        var n = Math.pow(10, p);
                        return Math.round(d * n) / n;
                    }
                }
            }

            function styleSpan() {
                var span = $(this);
                //setTimeout(function() {
                val = span.data('color') || span.html().replace(/['"]/g, '').trim();
                if (chroma[val]) {
                    span.attr('style', '');
                    return;
                }

                try {
                    var col = chroma(val),
                        l = col.oklch()[0];
                    span.attr(
                        'style',
                        [
                            'background-color:' + col.hex(),
                            'color:' + (l < 0.7 ? 'white' : 'black'),
                            'opacity:' + col.alpha()
                        ].join(';')
                    );
                } catch (e) {
                    //console.log(e);
                    span.attr('style', '');
                    // not a color, so ignore
                }
                //}, 50);
            }

            function enableSlider() {
                return;
                var span = $(this),
                    slider = $('<div></div>').addClass('slider'),
                    input = $('<input type="range" />').appendTo(slider);

                span.off('mouseenter').on('mouseenter', function () {
                    var v = +span.text(),
                        d = Math.pow(10, Math.max(1, Math.log10(v))),
                        min = v - d,
                        max = v + d;
                    input.attr({ min: min, max: max }).prop('value', v);
                    console.log('span', v);

                    span.append(slider);
                });
                span.off('mouseleave').on('mouseleave', function () {
                    //slider.remove();
                });
            }
        });

        var toc = $('<ul />')
            .addClass('toc')
            .appendTo($('<div>').addClass('toc-container').appendTo('.wrap'));

        var hue = Math.random() * 360;
        $('h2,h3').each(function () {
            var h = $(this),
                l = h.attr('id'),
                t = h.is('h2');
            toc.append(
                '<li class="' +
                    ('level-' + (t ? '1' : '2')) +
                    '"><a style="color:' +
                    chroma.lch(50, 80, hue) +
                    '" href="#' +
                    l +
                    '">' +
                    h.text() +
                    '</a></li>'
            );
            hue = (hue + 20) % 360;
            var a = $('<a />')
                .attr('href', '#' + l)
                .html(h.html());
            h.html('').append(a);
        });

        $('h3+h4').each(function (i, el) {
            el.previousElementSibling.appendChild(el);
        });
    })(jQuery);
</script>
<a href="https://github.com/gka/chroma.js" class="github-corner"
    ><svg
        width="80"
        height="80"
        viewBox="0 0 250 250"
        style="fill: #64ceaa; color: #fff; position: absolute; top: 0; border: 0; right: 0"
    >
        <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
        <path
            d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
            fill="currentColor"
            style="transform-origin: 130px 106px"
            class="octo-arm"
        ></path>
        <path
            d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
            fill="currentColor"
            class="octo-body"
        ></path></svg
></a>
<style>
    .github-corner:hover .octo-arm {
        animation: octocat-wave 560ms ease-in-out;
    }
    @keyframes octocat-wave {
        0%,
        100% {
            transform: rotate(0);
        }
        20%,
        60% {
            transform: rotate(-25deg);
        }
        40%,
        80% {
            transform: rotate(10deg);
        }
    }
    @media (max-width: 500px) {
        .github-corner:hover .octo-arm {
            animation: none;
        }
        .github-corner .octo-arm {
            animation: octocat-wave 560ms ease-in-out;
        }
    }
</style>
